package com.yx.outSourcing.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.yx.outSourcing.entity.vo.AccessApplicationDetailVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yx.outSourcing.entity.dto.AccessApplicationDTO;
import com.yx.outSourcing.entity.po.AccessApplication;
import com.yx.outSourcing.entity.po.DeleteApplication;
import com.yx.outSourcing.entity.po.OutsourcingPerson;
import com.yx.outSourcing.entity.vo.AccessApplicationVO;
import com.yx.outSourcing.entity.vo.OutsourcingPersonVO;
import com.yx.outSourcing.enums.AppStatus;
import com.yx.outSourcing.mapper.AccessApplicationMapper;
import com.yx.outSourcing.mapper.DeleteApplicationMapper;
import com.yx.outSourcing.mapper.DeleteOutsourcingMapper;
import com.yx.outSourcing.mapper.OutsourcingPersonMapper;
import com.yx.outSourcing.service.IAccessApplicationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 外协人员信息表 服务实现类
 * </p>
 *
 * @author zcc
 * @since 2025-07-29
 */


@Service
public class AccessApplicationServiceImpl extends ServiceImpl<AccessApplicationMapper, AccessApplication> implements IAccessApplicationService {

    @Autowired
    private AccessApplicationMapper accessApplicationMapper;
    @Autowired
    private OutsourcingPersonMapper outsourcingPersonMapper;
    @Autowired
    private DeleteApplicationMapper deleteApplicationMapper;
    @Autowired
    private DeleteOutsourcingMapper deleteOutsourcingMapper;
    @Autowired
    private PlatformTransactionManager transactionManager;


    @Transactional
    @Override
    public void deleteApplication(Long id) {
        // 1. 查询原数据
        AccessApplication application = getById(id);
        if (application == null) throw new RuntimeException("申请单不存在");

        // 2. 转移数据到删除表（新事务）
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        transactionTemplate.execute(status -> {
            // 2.1 创建删除记录
            DeleteApplication deleteRecord = new DeleteApplication();
            BeanUtils.copyProperties(application, deleteRecord);
            deleteRecord.setId(null); // 关键：清空ID

            // 2.2 插入删除表
            deleteApplicationMapper.insert(deleteRecord);

            // 2.3 处理关联人员（如果有）
            List<OutsourcingPerson> persons = outsourcingPersonMapper.selectList(
                    new LambdaQueryWrapper<OutsourcingPerson>().eq(OutsourcingPerson::getAppId, id)
            );
            if (!persons.isEmpty()) {
                persons.forEach(p -> p.setAppId(deleteRecord.getId()));
                persons.forEach(p -> p.setPerId(null)); // 清空人员ID
                deleteOutsourcingMapper.batchInsert(persons);
            }
            return null;
        });

        // 3. 删除原数据
        outsourcingPersonMapper.delete(
                new LambdaQueryWrapper<OutsourcingPerson>().eq(OutsourcingPerson::getAppId, id)
        );
        removeById(id);
    }

    @Override
    public Page<AccessApplicationVO> appList() {
//        List<AccessApplication> list = list();
//        List<AccessApplicationVO> vos = BeanUtil.copyToList(list, AccessApplicationVO.class);

        // 创建分页对象，使用传入的分页参数
        Page<AccessApplication> page = new Page<>(1, 10);

        // 使用分页查询获取数据
        Page<AccessApplication> pageResult = page(page);

        // 转换数据实体为VO对象
        List<AccessApplicationVO> vos = BeanUtil.copyToList(pageResult.getRecords(), AccessApplicationVO.class);
        // 创建返回的分页对象
        Page<AccessApplicationVO> resultPage = new Page<>(pageResult.getCurrent(), pageResult.getSize(), pageResult.getTotal());
        resultPage.setRecords(vos.stream()
                .map(vo -> {
                    AccessApplicationVO personVO = new AccessApplicationVO();
                    BeanUtils.copyProperties(vo, personVO);
                    return personVO;
                })
                .collect(Collectors.toList()));

        return resultPage;
    }

    @Override
    public Long createApplication(AccessApplicationDTO dto) {
        // 1. 生成申请单号
        String appNo = generateApplicationNo();
        // 2. 根据app_unit查找已存在的app_uid
        Long appUid = accessApplicationMapper.selectAppUidByAppUnit(dto.getAppUnit());

        // 3. 如果不存在则生成新的app_uid（使用时间戳+随机数保证唯一性）
        if (appUid == null) {
            appUid = System.currentTimeMillis() + (long)(Math.random() * 1000);
        }

        // 4. 根据out_unit查找已存在的out_uid
        Long outUid = accessApplicationMapper.selectOutUidByOutUnit(dto.getOutUnit());

        // 5. 如果不存在则生成新的out_uid
        if (outUid == null) {
            outUid = System.currentTimeMillis() + (long)(Math.random() * 1000);
        }

        // 6. 构建实体对象
        AccessApplication entity = new AccessApplication()
                .setAppNo(appNo)
                .setAppUnit(dto.getAppUnit())
                .setAppPerson(dto.getAppPerson())
                .setEntryCount(dto.getEntryCount())
                .setOutUnit(dto.getOutUnit())
                .setArea(dto.getArea())
                .setOutContact(dto.getOutContact())
                .setOutPhone(dto.getOutPhone())
                .setContent(dto.getContent())
                .setAppDate(LocalDate.now())
                .setAppUid(appUid) // 使用查询或生成的app_uid
                .setOutUid(outUid)
                .setStatus(AppStatus.NEW) // 0-新建
                .setCreateBy(dto.getAppPerson()) // 创建人员-申请人
                .setUpdataBy(dto.getAppPerson()) // 修改人员-申请人
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());

        // 5. 保存到数据库
        accessApplicationMapper.insert(entity);
        return entity.getId();
    }

//    @Override
//    public void updateApplication(Long id, AccessApplicationDTO dto) {
//        // 1. 先查询现有记录
//        AccessApplication existingEntity = getById(id);
//        if (existingEntity == null) {
//            throw new RuntimeException("申请单不存在");
//        }
//
//        // 2. 处理app_uid: 如果app_unit变更，则重新获取或生成app_uid
//        Long appUid = existingEntity.getAppUid(); // 保留原有app_uid
//        if (!dto.getAppUnit().equals(existingEntity.getAppUnit())) {
//            // 如果申请单位变更，则重新查找或生成app_uid
//            appUid = accessApplicationMapper.selectAppUidByAppUnit(dto.getAppUnit());
//            if (appUid == null) {
//                appUid = System.currentTimeMillis() + (long)(Math.random() * 1000);
//            }
//        }
//
//        // 3. 处理out_uid: 如果out_unit变更，则重新获取或生成out_uid
//        Long outUid = existingEntity.getOutUid(); // 保留原有out_uid
//        if (!dto.getOutUnit().equals(existingEntity.getOutUnit())) {
//            // 如果外协单位变更，则重新查找或生成out_uid
//            outUid = accessApplicationMapper.selectOutUidByOutUnit(dto.getOutUnit());
//            if (outUid == null) {
//                outUid = System.currentTimeMillis() + (long)(Math.random() * 1000);
//            }
//        }}
        // 4. 更新实体对象（只更新变更字段）
    @Override
    public AccessApplicationDetailVO getApplicationDetail(Long id) {
        // 1. 查询申请单信息
        AccessApplication application = getById(id);
        if (application == null) {
            throw new RuntimeException("申请单不存在");
        }

        // 2. 转换为VO对象
        AccessApplicationDetailVO detailVO = new AccessApplicationDetailVO();
        BeanUtils.copyProperties(application, detailVO);
//        detailVO.setStatus(application.getStatus());

        // 3. 查询关联的外协人员列表
        List<OutsourcingPerson> persons = outsourcingPersonMapper.selectList(
                new LambdaQueryWrapper<OutsourcingPerson>().eq(OutsourcingPerson::getAppId, id)
        );

        // 4. 转换人员列表为VO
        List<OutsourcingPersonVO> personVOs = persons.stream()
                .map(person -> {
                    OutsourcingPersonVO vo = new OutsourcingPersonVO();
                    BeanUtils.copyProperties(person, vo);
                    vo.setCompanyName(application.getOutUnit());
                    vo.setWorkArea(application.getArea());
                    // 计算照片数量
                    int photoCount = 0;
                    if (person.getIdCardFront() != null && !person.getIdCardFront().isEmpty()) {
                        photoCount++;
                    }
                    if (person.getIdCardBack() != null && !person.getIdCardBack().isEmpty()) {
                        photoCount++;
                    }
                    if (person.getPortraitPhoto() != null && !person.getPortraitPhoto().isEmpty()) {
                        photoCount++;
                    }
                    vo.setPhotoCount(photoCount);
                    return vo;
                })
                .collect(Collectors.toList());

        // 5. 设置人员列表到详情VO
        detailVO.setOutsourcingPersons(personVOs);

        return detailVO;
    }

    @Override
    public void updateApplication(Long id, AccessApplicationDTO dto) {
        // 1. 先查询现有记录
        AccessApplication existingEntity = getById(id);
        if (existingEntity == null) {
            throw new RuntimeException("申请单不存在");
        }

        // 2. 处理app_uid: 如果app_unit变更，则重新获取或生成app_uid
        Long appUid = existingEntity.getAppUid(); // 保留原有app_uid
        if (!dto.getAppUnit().equals(existingEntity.getAppUnit())) {
            // 如果申请单位变更，则重新查找或生成app_uid
            appUid = accessApplicationMapper.selectAppUidByAppUnit(dto.getAppUnit());
            if (appUid == null) {
                appUid = System.currentTimeMillis() + (long)(Math.random() * 1000);
            }
        }

        // 3. 处理out_uid: 如果out_unit变更，则重新获取或生成out_uid
        Long outUid = existingEntity.getOutUid(); // 保留原有out_uid
        if (!dto.getOutUnit().equals(existingEntity.getOutUnit())) {
            // 如果外协单位变更，则重新查找或生成out_uid
            outUid = accessApplicationMapper.selectOutUidByOutUnit(dto.getOutUnit());
            if (outUid == null) {
                outUid = System.currentTimeMillis() + (long)(Math.random() * 1000);
            }
        }

        // 4. 更新实体对象（只更新变更字段）
        existingEntity
                .setAppUnit(dto.getAppUnit())
                .setAppPerson(dto.getAppPerson())
                .setEntryCount(dto.getEntryCount())
                .setOutUnit(dto.getOutUnit())
                .setArea(dto.getArea())
                .setOutContact(dto.getOutContact())
                .setOutPhone(dto.getOutPhone())
                .setContent(dto.getContent())
                .setAppUid(appUid)  // 更新app_uid
                .setOutUid(outUid)  // 更新out_uid
                .setStatus(AppStatus.NEW) // 0-新建
                .setUpdataBy(dto.getAppPerson())
                .setUpdateTime(LocalDateTime.now()); // 只更新修改时间，不更新创建时间

        // 5. 更新到数据库
        updateById(existingEntity);
    }


    /**
     * 生成申请单号（yyyymmdd+3位流水码）
     */
    private String generateApplicationNo() {
        // 1. 获取当天日期
        String datePart = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 2. 查询当天最大流水号
        Integer maxSeq = accessApplicationMapper.selectMaxSeqByDate(LocalDate.now());
        int nextSeq = (maxSeq == null) ? 1 : maxSeq + 1;

        // 3. 格式化为3位数字
        String seqPart = String.format("%03d", nextSeq);

        return datePart + seqPart;
    }
}
